﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Perceiveit.Xml.Tests.Concrete
{
    /// <summary>
    /// Complex entity that has an inner collection of items without an element name to encapsulate identify the items
    /// </summary>
    public class DefaultListWrapper : XEntity, IEnumerable<DefaultInnerType>
    {
        public static XPropertyList<DefaultInnerType> _inneritems = XProperty.List<DefaultInnerType>(null,
                                                                            new XChoiceFactory<DefaultInnerType>(
                                                                                XSubClassFactory.Simple<DefaultInnerType,InnerType1>("type-1", Root.XmlNamespace),
                                                                                XSubClassFactory.Simple<DefaultInnerType,InnerType2>("type-2", Root.XmlNamespace)));

        public static XProperty<string> _id = XProperty.Attribute<string>("id");
        public static XProperty<string> _desc = XProperty.Attribute<string>("desc");

        public string ID
        {
            get { return _id.GetValue(this); }
            set { _id.SetValue(this, value); }
        }

        public string Description
        {
            get { return _desc.GetValue(this); }
            set { _desc.SetValue(this, value); }
        }

        protected XList<DefaultInnerType> InnerItems
        {
            get
            {
                XList<DefaultInnerType> value = _inneritems.GetValue(this);
                if (null == value)
                {
                    value = _inneritems.Create();
                    _inneritems.SetValue(this, value);
                }
                return value;
            } 
        }

        //
        // methods working on the inner collection - could just expose the collection through XList<DefaultInnerType> Items {get;}
        //

        public DefaultInnerType this[int index]
        {
            get { return InnerItems[index]; }
            set { InnerItems[index] = value; }
        }

        public int Count
        {
            get { return this.InnerItems.Count; }
        }

        public void Clear()
        {
            this.InnerItems.Clear();
        }

        public void RemoveAt(int index)
        {
            this.InnerItems.RemoveAt(index);
        }


        public IEnumerator<DefaultInnerType> GetEnumerator()
        {
            return this.InnerItems.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }


    //
    // inner item classes
    //

    public abstract class DefaultInnerType : XEntity
    {
        private static XProperty<string> _desc = XProperty.Text<string>();

        public static XProperty<string> _id = XProperty.Attribute<string>("id");
        public static XProperty<string> _name = XProperty.Attribute<string>("name");

        public string Description
        {
            get { return _desc.GetValue(this); }
            set { _desc.SetValue(this, value); }
        }
    }


    public class InnerType1 : DefaultInnerType
    {
        public string ID
        {
            get { return _id.GetValue(this); }
            set { _id.SetValue(this, value); }
        }

        
    }

    public class InnerType2 : DefaultInnerType
    {
        public string Name
        {
            get { return _name.GetValue(this); }
            set { _name.SetValue(this, value); }
        }
    }
}
